<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0"
	xmlns="http://www.w3.org/1999/xhtml"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:xsd="http://www.w3.org/2001/XMLSchema"
	xmlns:ev="http://www.w3.org/2001/xml-events"
	xmlns:ccts="urn:un:unece:uncefact:documentation:standard:CoreComponentsTechnicalSpecification:2"
	xmlns:xf="http://www.w3.org/2002/xforms"
	exclude-result-prefixes="xsd xsl"> 
	
	<xsl:import href="global-vars.xsl"/>
	<xsl:import href="global-templates.xsl"/>
	
	<xsl:import href="AmountType.xsl" />
	<xsl:import href="BinaryObjectType.xsl" />
	<xsl:import href="CodeType.xsl" />
	<xsl:import href="DateTimeType.xsl" />
	<xsl:import href="IDType.xsl" />
	<xsl:import href="IndicatorType.xsl" />
	<xsl:import href="MeasureType.xsl" />
	<xsl:import href="NumericType.xsl" />
	<xsl:import href="NameType.xsl" />
	<xsl:import href="QuantityType.xsl" />
	<xsl:import href="TextType.xsl" />
	
	<!-- 
		This template starts generation of the gui part from the XForms document. It creates a
		div for the root element of the message and then calls the template GuiElements to walk
		through the rest of the message.
	-->
	<xsl:template name="GenerateGui">
		<xsl:param name="type" />
		<xsl:param name="prefix" />
		
		<xsl:variable name="den" select="/xsd:schema/xsd:complexType[@name = substring-after( $type, ':' )]
			/xsd:annotation/xsd:documentation/ccts:DictionaryEntryName" />
		
		<xsl:variable name="ref">instance('<xsl:value-of 
			select="$global.instance.message" />')</xsl:variable>
		
		<xsl:element name="div" namespace="http://www.w3.org/1999/xhtml">
			<xsl:attribute name="class" select="replace( replace( $den, ' ', '' ), '\.', '__' )" />
			<xsl:element name="xf:label">
				<xsl:value-of select="xsd:annotation/xsd:documentation/ccts:Name" />
			</xsl:element>
			
			<xsl:call-template name="GuiElements">
				<xsl:with-param name="element.type" select="$type" />
				<xsl:with-param name="element.ref" select="$ref" />
				<xsl:with-param name="element.prefix" select="$prefix"/>
			</xsl:call-template>
		</xsl:element>
	</xsl:template>
	
	<!--
		Generates the gui elements for each element found in the message.
	-->
	<xsl:template name="GuiElements">
		<xsl:param name="element.type" />
		<xsl:param name="element.ref" />
		<xsl:param name="element.prefix" />
		<xsl:param name="element.schema" />
		
		<xsl:if test="if( not( contains( $element.type, ':') ) )
			then error( QName( 'E', 'E' ), concat( 'gui.xsl : GuiElements : element.type must contain a prefix - value = ', $element.type ) )
			else true()" />
		
		<xsl:variable name="element.type.children">
			<xsl:call-template name="GetChildElements">
				<xsl:with-param name="parent" select="substring-after( $element.type, ':' )" />
				<xsl:with-param name="parent.schema" select="$element.schema" />
			</xsl:call-template>			
		</xsl:variable>
		
		<xsl:for-each select="$element.type.children/xsd:element">
			<xsl:sort select="position" />
			
			<xsl:variable name="element.ref" select="if( $element.ref = '' ) 
				then concat( $element.prefix, ':', @name )
				else concat( $element.ref, '/', $element.prefix, ':', @name )" />
			
			<xsl:choose>
				<xsl:when test="@maxOccurs = 'unbounded' or @maxOccurs > 1">
					<xsl:variable name="repeat.id">repeat.<xsl:value-of select="generate-id()" /></xsl:variable>
					
					<xsl:element name="xf:repeat">
						<xsl:attribute name="nodeset"><xsl:value-of select="$element.ref" /></xsl:attribute>
						<xsl:attribute name="id" select="$repeat.id" />
						
						<xsl:call-template name="HandleChildren" >
							<xsl:with-param name="element.schema" select="$element.schema" />
							<xsl:with-param name="element.ref"></xsl:with-param>
							<xsl:with-param name="element.prefix" select="$element.prefix" />
						</xsl:call-template>
						
						<xsl:element name="xf:trigger">
							<xsl:element name="xf:label">Delete <xsl:value-of 
								select="xsd:annotation/xsd:documentation/ccts:BusinessTermName" /></xsl:element>
							<xsl:element name="xf:delete">
								<xsl:attribute name="nodeset" select="$element.ref" />
								<xsl:attribute name="at">index('<xsl:value-of select="$repeat.id"/>' )</xsl:attribute>
								<xsl:attribute name="ev:event">DOMActivate</xsl:attribute>
							</xsl:element>
						</xsl:element>
					</xsl:element>
					<xsl:element name="xf:trigger">
						<xsl:element name="xf:label">New  <xsl:value-of 
							select="xsd:annotation/xsd:documentation/ccts:BusinessTermName" />
						</xsl:element>
						<xsl:element name="xf:action">
							<xsl:attribute name="ev:event">DOMActivate</xsl:attribute>
							<xsl:element name="xf:insert">
								<xsl:attribute name="nodeset" select="$element.ref" />
								<xsl:attribute name="position">before</xsl:attribute>
								<xsl:attribute name="at">count( <xsl:value-of select="$element.ref" /> )</xsl:attribute>
							</xsl:element>
						</xsl:element>
					</xsl:element>
				</xsl:when>
				<xsl:otherwise>
					<xsl:call-template name="HandleChildren" >
						<xsl:with-param name="element.schema" select="$element.schema" />
						<xsl:with-param name="element.ref" select="$element.ref" />
						<xsl:with-param name="element.prefix" select="$element.prefix" />
					</xsl:call-template>
				</xsl:otherwise>
			</xsl:choose>
		</xsl:for-each>
	</xsl:template>
	
	<xsl:template name="HandleChildren">
		<xsl:param name="element.schema" />
		<xsl:param name="element.prefix" />
		<xsl:param name="element.ref" />
		
		<xsl:choose>
			<xsl:when test="xsd:annotation/xsd:documentation/ccts:Acronym = 'BBIE'">
				<!-- 
					At this moment we have a qualified or unqualified datatype. The bindings that are
					defined for the unqualified datatypes should be looked up here.
				-->
				<xsl:variable name="element.type.schema">
					<xsl:call-template name="GetDataTypeDocument">
						<xsl:with-param name="element.type" select="@type" />
						<xsl:with-param name="element.schema" select="$element.schema" />
					</xsl:call-template>
				</xsl:variable>
				<xsl:call-template name="HandleDataType">
					<xsl:with-param name="element.type" select="@type" />
					<xsl:with-param name="element.type.schema" select="$element.type.schema" />
					<xsl:with-param name="element.businessterm" 
						select="xsd:annotation/xsd:documentation/ccts:BusinessTerm"/>
					<xsl:with-param name="element.den" 
						select="xsd:annotation/xsd:documentation/ccts:DictionaryEntryName" />
					<xsl:with-param name="element.ref" select="$element.ref" />
				</xsl:call-template>
			</xsl:when>
			<xsl:otherwise>
				<xsl:variable name="childElementNS" 
					select="namespace-uri-for-prefix( substring-before( @type, ':' ), . )"/>
				
				<xsl:variable name="documentNS" select="if( $element.schema = '' ) 
					then document( $global.schema.root )/xsd:schema/@targetNamespace
					else document( $element.schema )/xsd:schema/@targetNamespace"/>
				
				<xsl:element name="div">
					<xsl:attribute name="class"><xsl:value-of 
						select="replace( 
						replace( xsd:annotation/xsd:documentation/ccts:DictionaryEntryName, ' ', '' )
						, '\.', '__' )" /></xsl:attribute>
					<xsl:element name="xf:label">
						<xsl:value-of select="xsd:annotation/xsd:documentation/ccts:BusinessTerm"/>
					</xsl:element>
					<xsl:choose>
						<xsl:when test="$documentNS != $childElementNS">
							<xsl:variable name="nextDoc"
								select="if( $element.schema = '')
								then document( $global.schema.root )/xsd:schema/xsd:import[
									@namespace = $childElementNS]/@schemaLocation
								else document( $element.schema )/xsd:schema/xsd:import[
									@namespace = $childElementNS]/@schemaLocation"/>
							
							<xsl:variable name="prefix.next" select="substring-before( @type, ':' )"/>
							
							<xsl:call-template name="GuiElements">
								<xsl:with-param name="element.type" select="@type"/>
								<xsl:with-param name="element.ref" select="$element.ref" />
								<xsl:with-param name="element.prefix" select="$prefix.next" />
								<xsl:with-param name="element.schema" select="$nextDoc" />
							</xsl:call-template>
						</xsl:when>
						<xsl:otherwise>
							<xsl:call-template name="GuiElements">
								<xsl:with-param name="element.type" select="@type"/>
								<xsl:with-param name="element.ref" select="$element.ref" />
								<xsl:with-param name="element.prefix" select="$element.prefix" />
								<xsl:with-param name="element.schema" select="$element.schema" />
							</xsl:call-template>
						</xsl:otherwise>
					</xsl:choose>
				</xsl:element>
			</xsl:otherwise>
		</xsl:choose>
	</xsl:template>
	
	<!-- 
		The document is the document in which the datatype is declared. To get the defenition of the datatype
		the import within this document must be used to see where it is described.
	-->
	<xsl:template name="HandleDataType">
		<xsl:param name="element.type" required="yes" />
		<xsl:param name="element.type.schema" required="yes" />
		<xsl:param name="element.businessterm" required="yes" />
		<xsl:param name="element.den" required="yes" />
		<xsl:param name="element.ref" required="yes" />
		
		<xsl:if test="if( not( contains( $element.type, ':') ) )
			then error( QName( 'E', 'E' ), concat( 'gui.xsl : HandleDataType : element.type must contain a prefix - value = ', $element.type ) )
			else true()" />
		
		<!-- First we have to look up on which unqualified datatype this type is based -->
		<xsl:variable name="element.type.unqualified">
			<xsl:call-template name="GetUnqualifiedDataType">
				<xsl:with-param name="element.type" select="$element.type" />
				<xsl:with-param name="element.type.schema" select="$element.type.schema" />
			</xsl:call-template>
		</xsl:variable>
		
		<!-- remove the namespace prefix -->
		<xsl:variable name="element.type.unqualified" 
			select="substring-after($element.type.unqualified, ':')" />
		
		<xsl:choose>
			<xsl:when test="$element.type.unqualified = 'AmountType' ">
				<xsl:call-template name="GenerateAmountTypeElements">
					<xsl:with-param name="element.type" select="$element.type" />
					<xsl:with-param name="element.type.schema" select="$element.type.schema" />
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'BinaryObjectType'">
				<xsl:call-template name="BinaryObjectTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'CodeType' ">
				<xsl:call-template name="GenerateCodeTypeElements" >
					<xsl:with-param name="element.type" select="$element.type" />
					<xsl:with-param name="element.type.schema" select="$element.type.schema" />
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'DateTimeType'">
				<xsl:call-template name="DateTimeTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'DateType'">
				<xsl:call-template name="DateTimeTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'TimeType'">
				<xsl:call-template name="DateTimeTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'IDType' ">
				<xsl:call-template name="GenerateIDTypeElements" >
					<xsl:with-param name="element.type" select="$element.type" />
					<xsl:with-param name="element.type.schema" select="$element.type.schema" />
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'IndicatorType'">
				<xsl:call-template name="IndicatorTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'MeasureType'">
				<xsl:call-template name="GenerateMeasureTypeElements" >
					<xsl:with-param name="element.type" select="$element.type" />
					<xsl:with-param name="element.type.schema" select="$element.type.schema" />
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'NameType'">
				<xsl:call-template name="GenerateNameTypeElements" >
					<xsl:with-param name="element.type" select="$element.type" />
					<xsl:with-param name="element.type.schema" select="$element.type.schema" />
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'NumericType'">
				<xsl:call-template name="GenerateNumericTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<!-- 
				These are all numeric types. This has to be changed in future to be able to change
				the look and feel per type. So that when the NumericType get another look and feel
				not all these types get that too. I'm too lazy to do it right now.
			-->
			<xsl:when test="$element.type.unqualified = 'ValueType'">
				<xsl:call-template name="GenerateNumericTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'PercentType'">
				<xsl:call-template name="GenerateNumericTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'RateType'">
				<xsl:call-template name="GenerateNumericTypeElements" >
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<!-- End of NumericTypes -->
			<xsl:when test="$element.type.unqualified = 'QuantityType'">
				<xsl:call-template name="GenerateQuantityTypeElements" >
					<xsl:with-param name="element.type" select="$element.type" />
					<xsl:with-param name="element.type.schema" select="$element.type.schema" />
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
			<xsl:when test="$element.type.unqualified = 'TextType'">
				<xsl:call-template name="GenerateTextTypeElements" >
					<xsl:with-param name="element.type" select="$element.type" />
					<xsl:with-param name="element.type.schema" select="$element.type.schema" />
					<xsl:with-param name="element.ref" select="$element.ref" />
					<xsl:with-param name="element.den" select="$element.den" />
					<xsl:with-param name="businessterm" select="$element.businessterm" />
				</xsl:call-template>
			</xsl:when>
		</xsl:choose>
	</xsl:template>
</xsl:stylesheet>